using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data;
using System.IO;
using System.Security.Principal;
using System.Windows;
using System.Xml;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
using Windows.Storage;
using System.Runtime.Serialization;

namespace Enterprise_Store
{
    public partial class DataBinding : Application
    {        
        
        
        private List<AppPackage> installedApps;
        private xmlConfFile w8csConf;
        private AppPackage currentApp = null;
        private AppPackage installedSelectedItem = null;
        private AppPackage w8csSelectedItem = null;

        void AppStartup(object sender, StartupEventArgs args)
        {
            LoadAuctionData();
            MainWindow mainWindow = new MainWindow(this);
            mainWindow.Show();
            w8csConf = new xmlConfFile();

        }


        public AppPackage CurrentApp
        {
            get { return this.currentApp; }
            set { this.currentApp = value; }
        }

        public AppPackage InstalledSelectedItem
        {
            get { return this.installedSelectedItem; }
            set { this.installedSelectedItem = value; }
        }

        public AppPackage W8CSSelectedItem
        {
            get { return this.w8csSelectedItem; }
            set { this.w8csSelectedItem = value; }
        }

        public xmlConfFile W8CSConf
        {
            get { return this.w8csConf; }
            set { this.w8csConf = value; }
        }

        public List<AppPackage> InstalledApps
        {
            get { return this.installedApps; }
            set { this.installedApps = value; }
        }

        private void LoadAuctionData()
        {
            PackageManager manager = new PackageManager();
            IEnumerable<Package> temp = manager.FindPackagesForUser(/*null after CP*/ WindowsIdentity.GetCurrent().User.Value);
            
            installedApps = new List<AppPackage>();
            AppPackage tempApp = null;

            foreach(Package app in temp){
                tempApp = new AppPackage(app);
                if (tempApp.AppList.Count != 0)
                {
                    installedApps.Add(tempApp);
                }

            }
        }

        private void writeW8CSConfFile()
        {
            FileStream fs = new FileStream(@"c:\temp\testapp.xml", FileMode.Create);
            XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs);
            DataContractSerializer ser =
                new DataContractSerializer(typeof(xmlConfFile));
            ser.WriteObject(writer, w8csConf);
            Console.WriteLine("Finished writing object.");
            writer.Close();
            fs.Close();

        }

        private void typeOfApp_SelectionChanged_1(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (true)
            {

            }
        }
    }

    [DataContract(Name="Application")]
    public class AppPackage
    {

        public AppPackage()
        {
            this.package = null;
            this.appList = new List<App>();
            this.typeOfLink = 2;            
        }
        
        public AppPackage(Package pack)
        {
            this.package = pack;
            this.appList = new List<App>();
            this.typeOfLink = 1;
            load();
        }


        private void load()
        {
            if (this.package == null)
                return;

            try
            {
                XmlDocument packageManifest = new XmlDocument();

                if (File.Exists(this.package.InstalledLocation.Path + @"\AppxManifest.xml"))
                {

                    packageManifest.Load(this.package.InstalledLocation.Path + @"\AppxManifest.xml");
                    //packageManifest.Load(@"c:\temp\AppxManifest.xml");
                    //packageManifest.Load(@"c:\temp\StoreStructure.xml");
                    XmlNode root = packageManifest.DocumentElement;

                    if (packageManifest != null)
                    {
                        XmlNodeList apps = null;
                        int nbApps = 0;
                        XmlNamespaceManager xmlName = new XmlNamespaceManager(packageManifest.NameTable);

                        xmlName.AddNamespace("x","http://schemas.microsoft.com/appx/2010/manifest");
                        xmlName.AddNamespace("build", "http://schemas.microsoft.com/developer/appx/2012/build");

                        apps = root.SelectNodes("//x:Application", xmlName);

                        nbApps = apps.Count;
                     
                        App temp;

                        for (int cpt = 0; cpt < nbApps; cpt++)
                        {
                            temp = new App(apps.Item(cpt).Attributes.GetNamedItem("Id").InnerText,apps.Item(cpt).SelectSingleNode("//x:VisualElements", xmlName).Attributes.GetNamedItem("DisplayName").InnerText);
                            
                            this.appList.Add(temp);
                        }
                    }
                }
            }
            catch (Exception e)
            {

            }
        }


        private Package package;
        private List<App> appList;
        private string displayedName;
        private string shortDesc;
        private string msStoreID;
        private Boolean isDeepLink;
        private string hyperlink;
        private string logo;
        private int appID;
        private string path;
        private string commandLine;

        /*
         * 0: internal modern app
         * 1: windows store app
         * 2: windows desktop app
         **/
        private int typeOfLink;

        public List<App> AppList
        {
            get { return this.appList; }
            set { this.appList = value; }
        }



        public int AppID
        {
            get { return this.appID; }
            set { this.appID = value; }
        }

        public string AppName
        {
            get { 
                if(appList == null)
                    return "";
                if(appList.Count <= AppID)
                    return "";
                return this.appList[AppID].Id;
            }

        }

        public string FirstAppName
        {
            get
            {
                if (appList == null || appList.Count == 0)
                    return "";
                else
                    return this.appList[0].Id + "-" + this.appList[0].Name;
            }
        }

        public Package Package
        {
            get { return this.package; }
            set { this.package = value; }
        }

        [DataMember]
        public string Name
        {
            get {
                if (package != null)
                    return this.package.Id.Name;
                else return "";
            }
            set { }
        }

        public String IsDeepLink
        {
            get
            {
                return this.isDeepLink?"TRUE":"FALSE";
            }
            set
            {
                this.isDeepLink = value.ToUpper()=="TRUE";
            }
        }

        public string Version
        {
            get {
                if (package == null)
                    return "";
                if (package.Id == null)
                    return "";

                return this.package.Id.Version.Major + "." + this.package.Id.Version.Minor + "." + this.package.Id.Version.Build + "." + this.package.Id.Version.Revision; }
        }

        [DataMember]
        public string DisplayedName
        {
            get {
                if (this.displayedName == String.Empty || this.displayedName == null)
                    return this.Name;
                else
                    return this.displayedName; 
            }
            set { this.displayedName = value; }
        }

        [DataMember]
        public string ShortDesc
        {
            get { return this.shortDesc; }
            set { this.shortDesc = value; }
        }

        [DataMember]
        public string MsStoreID
        {
            get
            {
                if (this.typeOfLink != 1)
                    return "";

                if ((this.msStoreID == String.Empty || this.msStoreID == null) && this.package != null)
                    return this.package.Id.Name + "_" + this.package.Id.PublisherId;
                else 
                    return this.msStoreID;
            }
            set { this.msStoreID = value; }
        }

        public string Path
        {
            get {
                if (this.path != null)
                    return this.path.Replace(@"\", "%5C").Replace(" ", "%20");
                else
                    return "";
            }
            set { this.path = value; }
        }


        public string CommandLine
        {
            get { return this.commandLine; }
            set { this.commandLine = value; }
        }


        [DataMember]
        public string Hyperlink
        {
            get {
                    this.hyperlink = "";

                    switch (this.TypeOfLink)
                    {
                        case 0: this.hyperlink += "internalWin8App?"; 
                                this.hyperlink += "PackageName=" + this.Name +"&";
                                this.hyperlink += "AppId=" + this.AppName+ "&";
                                this.hyperlink += "Path=" + this.Path; break;
                        case 1: this.hyperlink += "WINDOWSSTOREWIN8APP?"; 
                                this.hyperlink += "PackageName=" + this.Name + "&";
                                this.hyperlink += "AppId=" + this.AppName + "&";
                                this.hyperlink += "storeID=" + this.MsStoreID; break;
                        case 2: this.hyperlink += "WindowsLegacyAPP?"; 
                                this.hyperlink += "Path="+this.CommandLine; break;
                    }
                
                return this.hyperlink; 
            }
            
            set {
                if (value.Contains("internalWin8App")) typeOfLink = 0;
                else if (value.Contains("WINDOWSSTOREWIN8APP")) typeOfLink = 1;
                else if (value.Contains("WindowsLegacyAPP")) typeOfLink = 2;
                else typeOfLink = 3;

                this.hyperlink = value; }
        }

        public int TypeOfLink
        {
            get { return this.typeOfLink; }
            set { this.typeOfLink = value; }
        }

        public string Logo
        {
            get { return this.logo; }
            set { this.logo = value; }
        }

        public string Xml
        {
            get
            {
                String xml = "<Application>" + System.Environment.NewLine;
                xml += "\t<Name>" + @"<![CDATA[" + this.DisplayedName + "]]></Name>" + System.Environment.NewLine;
                xml += "\t<ShortDescription>" + @"<![CDATA[" + this.ShortDesc + "]]></ShortDescription>" + System.Environment.NewLine;
                xml += "\t<MSStoreID>" + this.MsStoreID + "</MSStoreID>" + System.Environment.NewLine;
                xml += "\t<Logo>" + @"<![CDATA[" + this.Logo + "]]></Logo>" + System.Environment.NewLine;
                if (this.isDeepLink)
                {
                    xml += "\t<HyperLink>" + @"ms-windows-store:PDP?PFN=" + this.MsStoreID + "</HyperLink>" + System.Environment.NewLine;
                }
                else
                {
                    xml += "\t<HyperLink>" + @"<![CDATA[daipp://" + this.Hyperlink + "]]></HyperLink>" + System.Environment.NewLine;
                }
                xml += "</Application>";
                return xml;
            }
                
                
        }
    }

    public class App
    {

        public App(string idp, string namep)
        {
            this.id = idp;
            this.name = namep;
        }

        private string id;
        private string name;

        public String Id
        {
            get { return this.id; }
            set { this.id = value; }
        }

        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }

        public string toString()
        {
            return Name;
        }
    }

    [DataContract(Name="xml")]
    public class xmlConfFile
    {
        private List<ApplicationGroup> apps;

        public xmlConfFile()
        {
            apps = new List<ApplicationGroup>();
        }

        [DataMember(Name="tobecopied")]
        public List<ApplicationGroup> Apps
        {
            get { return this.apps; }
            set { this.apps = value; }
        }
    }

    [CollectionDataContract(ItemName = "Application2")]
    public class ApplicationGroup : List<AppPackage>
    {
        /*private List<AppPackage> apps;

        public AppGroup()
        {
            apps = new List<AppPackage>();
        }

        [DataMember(Name="ApplicationGroup1")]
        public List<AppPackage> Apps
        {
            get { return this.apps; }
            set { this.apps = value; }
        }*/
    }
}